/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package camion.wroom.wroom;

import java.util.ArrayList;
import java.util.Scanner;

/**
 *
 * @author BAILO
 */
public class CamionWroomWroom {

    private ArrayList<Camion> petitCamionsDisponibles = new ArrayList<Camion>();       //liste des camions disponibles
    private ArrayList<Camion> moyenCamionsDisponibles = new ArrayList<Camion>();        //liste des camions disponibles
    private ArrayList<Camion> grandCamionsDisponibles = new ArrayList<Camion>();        //liste des camions disponibles
    private ArrayList<Camion> tresGrandCamionsDisponibles = new ArrayList<Camion>();        //liste des camions disponibles
    private ArrayList<Camion> petitCamionsLoues = new ArrayList<Camion>();         //liste des petit camions loués
    private ArrayList<Camion> moyenCamionsLoues = new ArrayList<Camion>();         //liste des camions moyens loués
    private ArrayList<Camion> grandCamionsLoues = new ArrayList<Camion>();         //liste des grand camions loués
    private ArrayList<Camion> tresGrandCamionsLoues = new ArrayList<Camion>();     //liste des très grands camions loués
    private int totalKilometres = 0;                                               // nombre total de kilomètres parcourus par tous les camions
    /**
     * Constructeur par défaut
     */
    public CamionWroomWroom() {
        //2 petits camions
        for (int i = 0; i < 2; i++) {
            petitCamionsDisponibles.add(new Camion(Type.PETIT));
        }
        //6 camions moyens
        for (int i = 0; i < 6; i++) {
            moyenCamionsDisponibles.add(new Camion(Type.MOYEN));
        }
        //5 grands camions
        for (int i = 0; i < 5; i++) {
            grandCamionsDisponibles.add(new Camion(Type.GRAND));
        }
        //2 très grands camions
        for (int i = 0; i < 2; i++) {
            tresGrandCamionsDisponibles.add(new Camion(Type.TRES_GRAND));
        }
    }

    public ArrayList<Camion> getGrandCamionsDisponibles() {
        return grandCamionsDisponibles;
    }

    public void setGrandCamionsDisponibles(ArrayList<Camion> grandCamionsDisponibles) {
        this.grandCamionsDisponibles = grandCamionsDisponibles;
    }

    public ArrayList<Camion> getGrandCamionsLoues() {
        return grandCamionsLoues;
    }

    public void setGrandCamionsLoues(ArrayList<Camion> grandCamionsLoues) {
        this.grandCamionsLoues = grandCamionsLoues;
    }

    public ArrayList<Camion> getMoyenCamionsDisponibles() {
        return moyenCamionsDisponibles;
    }

    public void setMoyenCamionsDisponibles(ArrayList<Camion> moyenCamionsDisponibles) {
        this.moyenCamionsDisponibles = moyenCamionsDisponibles;
    }

    public ArrayList<Camion> getMoyenCamionsLoues() {
        return moyenCamionsLoues;
    }

    public void setMoyenCamionsLoues(ArrayList<Camion> moyenCamionsLoues) {
        this.moyenCamionsLoues = moyenCamionsLoues;
    }

    public ArrayList<Camion> getPetitCamionsDisponibles() {
        return petitCamionsDisponibles;
    }

    public void setPetitCamionsDisponibles(ArrayList<Camion> petitCamionsDisponibles) {
        this.petitCamionsDisponibles = petitCamionsDisponibles;
    }

    public ArrayList<Camion> getPetitCamionsLoues() {
        return petitCamionsLoues;
    }

    public void setPetitCamionsLoues(ArrayList<Camion> petitCamionsLoues) {
        this.petitCamionsLoues = petitCamionsLoues;
    }

    public ArrayList<Camion> getTresGrandCamionsDisponibles() {
        return tresGrandCamionsDisponibles;
    }

    public void setTresGrandCamionsDisponibles(ArrayList<Camion> tresGrandCamionsDisponibles) {
        this.tresGrandCamionsDisponibles = tresGrandCamionsDisponibles;
    }

    public ArrayList<Camion> getTresGrandCamionsLoues() {
        return tresGrandCamionsLoues;
    }

    public void setTresGrandCamionsLoues(ArrayList<Camion> tresGrandCamionsLoues) {
        this.tresGrandCamionsLoues = tresGrandCamionsLoues;
    }

    /**
     * Affiche le menu principal
     */
    public static void afficherMenu() {
        System.out.println("\n§§§§§§§§§§§§§§§§§§§ Menu principal §§§§§§§§§§§§§§§§§§§");
        System.out.println("1- Afficher les tarifs et les capacités du camion");
        System.out.println("2- Afficher le nombre de camions loués et le nombre de camions disponibles");
        System.out.println("3- Evaluer les coûts de location");
        System.out.println("4- Louer un camion");
        System.out.println("5- Retourner un camion");
        System.out.println("6- Quitter le programme");
        System.out.print("Votre choix: ");
    }

    /**
     * Affiche les tarifs et les capacités des camions
     */
    public static void afficherTarifsCapacites() {
        System.out.println("***** Information concernant les tarifs de location et les capacites des camions *******");
        System.out.println("%%%%% Catégorie des petits camions %%%%%%%");
        System.out.println("Prix de location: " + CamionInfo.prixPetitCamion + " dollars");
        System.out.println("Poids maximal:    " + CamionInfo.poidsMaxPetitCamion + " livres");
        System.out.println("Volume maximal:   " + CamionInfo.volumeMaxPetitCamion + " pieds cubes");

        System.out.println("%%%%% Catégorie des camions moyens %%%%%%%");
        System.out.println("Prix de location: " + CamionInfo.prixMoyenCamion + " dollars");
        System.out.println("Poids maximal:    " + CamionInfo.poidsMaxMoyenCamion + " livres");
        System.out.println("Volume maximal:   " + CamionInfo.volumeMaxMoyenCamion + " pieds cubes");

        System.out.println("%%%%% Catégorie des grands camions %%%%%%%");
        System.out.println("Prix de location: " + CamionInfo.prixGrandCamion + " dollars");
        System.out.println("Poids maximal:    " + CamionInfo.poidsMaxGrandCamion + " livres");
        System.out.println("Volume maximal:   " + CamionInfo.volumeMaxGrandCamion + " pieds cubes");

        System.out.println("%%%%% Catégorie des très grands camions %%%%%%%");
        System.out.println("Prix de location: " + CamionInfo.prixTresGrandCamion + " dollars");
        System.out.println("Poids maximal:    " + CamionInfo.poidsMaxTresGrandCamion + " livres");
        System.out.println("Volume maximal:   " + CamionInfo.volumeMaxTresGrandCamion + " pieds cubes");
        System.out.println("\nPour toutes les catégories, on ne charge rien pour les 50 premiers kilomètres, ensuite on facture 3 dollars par kilomètre supplémentaire\n");
        System.out.println("*****************************************************************************************\n\n");

    }

    /**
     * affiche le nombre de camions loués et le nombre de camions disponibles (par catégorie)
     */
    public void afficherDisponibilite() {
        System.out.println("********** Disponibilité ***********");
        System.out.println("%%%%% Catégorie des petits camions %%%%%%%");
        System.out.println("Nombre de camions disponibles: " + petitCamionsDisponibles.size());
        System.out.println("Nombre de camions loués: " + petitCamionsLoues.size());
        System.out.println("%%%%% Catégorie des camions moyens %%%%%%%");
        System.out.println("Nombre de camions disponibles: " + moyenCamionsDisponibles.size());
        System.out.println("Nombre de camions loués: " + moyenCamionsLoues.size());
        System.out.println("%%%%% Catégorie des grands camions %%%%%%%");
        System.out.println("Nombre de camions disponibles: " + grandCamionsDisponibles.size());
        System.out.println("Nombre de camions loués: " + grandCamionsLoues.size());
        System.out.println("%%%%% Catégorie des très grand camions %%%%%%%");
        System.out.println("Nombre de camions disponibles: " + tresGrandCamionsDisponibles.size());
        System.out.println("Nombre de camions loués: " + tresGrandCamionsLoues.size());
        System.out.println("************************************\n");
    }

    /**
     * Evalue le cout de l'une location
     * @param poids poids demandé
     * @param volume volume demandé
     * @param kilometres nombre de kilomètre à parcourir
     * @throws Exception s'il n'existe pas de catégorie de camion pour le poids et le volume demandé
     */
    public void evaluerCoutLocation(int poids, int volume, int kilometres) throws Exception {
        if (!existeCategorie(poids, volume)) {
            throw new Exception("On ne disposons pas de camion pour le volume et le poids demandés");
        }
        int kilometreSupplementaire = kilometres <= 50 ? 0 : (kilometres - 50);
        int coutTransport = kilometreSupplementaire * CamionInfo.prixKilometre;
        if (poids <= CamionInfo.poidsMaxPetitCamion && volume <= CamionInfo.volumeMaxPetitCamion) {
            System.out.println("On vous propose un petit camion avec les tarifs ci-dessous:");
            System.out.println("Coût de location: " + CamionInfo.prixPetitCamion + " dollars");
            System.out.println("Coût de transport: " + coutTransport + " dollars");
        } else if (poids <= CamionInfo.poidsMaxMoyenCamion && volume <= CamionInfo.volumeMaxMoyenCamion) {
            System.out.println("On vous propose un camion moyen avec les tarifs ci-dessous:");
            System.out.println("Coût de location: " + CamionInfo.prixMoyenCamion + " dollars");
            System.out.println("Coût de transport: " + coutTransport + " dollars");
        } else if (poids <= CamionInfo.poidsMaxGrandCamion && volume <= CamionInfo.volumeMaxGrandCamion) {
            System.out.println("On vous propose un grand camion avec les tarifs ci-dessous:");
            System.out.println("Coût de location: " + CamionInfo.prixGrandCamion + " dollars");
            System.out.println("Coût de transport: " + coutTransport + " dollars");
        } else { // tres grand camion
            System.out.println("On vous propose un très grand camion avec les tarifs ci-dessous:");
            System.out.println("Coût de location: " + CamionInfo.prixTresGrandCamion + " dollars");
            System.out.println("Coût de transport: " + coutTransport + " dollars");
        }
    }

    /**
     * Vérifie qu'il existe une categorie de camion pour la location
     * @param poids poids de location demandé
     * @param volume volume de location demandé
     * @return true s'il existe une categorie de camion et false sinon
     */
    private boolean existeCategorie(int poids, int volume) {
        return poids <= CamionInfo.poidsMaxTresGrandCamion && volume <= CamionInfo.volumeMaxTresGrandCamion;
    }

    /**
     * Loue un camion
     */
    public void louerCamion() {
        System.out.println("~~~~~~~~~~ Location de camion ~~~~~~~~~~");
        if (petitCamionsDisponibles.isEmpty() && moyenCamionsDisponibles.isEmpty()
                && grandCamionsDisponibles.isEmpty() && tresGrandCamionsDisponibles.isEmpty()) {
            System.out.println("Aucun camion n'est disponible. Merci de votre compréhension");
        } else {
            afficherDisponibilite();
            Scanner sc = new Scanner(System.in);
            CamionWroomWroom.afficherCategorie();
            int choix = sc.nextInt();
            while (choix < 1 || choix > 4) {
                System.out.println("Votre choix est invalide \n");
                CamionWroomWroom.afficherCategorie();
                choix = sc.nextInt();
            }
            int kilometres, poids = 0, volume = 0;

            switch (choix) {
                case 1:
                    if (petitCamionsDisponibles.isEmpty()) {
                        System.out.println("Il n'existe aucun camion disponible dans la catégorie des petits camions");
                    } else {
                        petitCamionsLoues.add(petitCamionsDisponibles.get(0)); // loué le premier camion disponible
                        petitCamionsDisponibles.remove(0); //enleve le premier camion disponible dans la liste des camion disponibles                        
                        poids = CamionInfo.poidsMaxPetitCamion;
                        volume = CamionInfo.volumeMaxPetitCamion;
                    }
                    break;
                case 2:
                    if (moyenCamionsDisponibles.isEmpty()) {
                        System.out.println("Il n'existe aucun camion disponible dans la catégorie des camions moyens");
                    } else {
                        moyenCamionsLoues.add(moyenCamionsDisponibles.get(0)); // loué le premier camion disponible
                        moyenCamionsDisponibles.remove(0); //enleve le premier camion disponible dans la liste des camion disponibles
                        poids = CamionInfo.poidsMaxMoyenCamion;
                        volume = CamionInfo.volumeMaxMoyenCamion;
                    }
                    break;
                case 3:
                    if (grandCamionsDisponibles.isEmpty()) {
                        System.out.println("Il n'existe aucun camion disponible dans la catégorie des grands camions");
                    } else {
                        grandCamionsLoues.add(grandCamionsDisponibles.get(0)); // loué le premier camion disponible
                        grandCamionsDisponibles.remove(0); //enleve le premier camion disponible dans la liste des camion disponibles
                        poids = CamionInfo.poidsMaxGrandCamion;
                        volume = CamionInfo.volumeMaxGrandCamion;
                    }
                    break;
                case 4:
                    if (tresGrandCamionsDisponibles.isEmpty()) {
                        System.out.println("Il n'existe aucun camion disponible dans la catégorie des très grands camions");
                    } else {
                        tresGrandCamionsLoues.add(tresGrandCamionsDisponibles.get(0)); // loué le premier camion disponible
                        tresGrandCamionsDisponibles.remove(0); //enleve le premier camion disponible dans la liste des camion disponibles
                        poids = CamionInfo.poidsMaxTresGrandCamion;
                        volume = CamionInfo.volumeMaxTresGrandCamion;
                    }
            }
            if (poids != 0 && volume != 0) {
                System.out.print("Veuillez saisir le nombre de kilometres désiré: ");
                kilometres = sc.nextInt();
                while (kilometres < 0) {
                    System.out.println("Le nombre de kilometres saisi est invalide");
                    System.out.print("Veuillez saisir le nombre de kilometres désiré: ");
                    kilometres = sc.nextInt();
                }
                try {
                    totalKilometres += kilometres;
                    evaluerCoutLocation(poids, volume, kilometres);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        }
    }

    /**
     * retourne un camion
     */
    public void retournerCamion() {
        System.out.println("~~~~~~~~~~ Restitution de camion ~~~~~~~~~~");
        if (petitCamionsLoues.isEmpty() && moyenCamionsLoues.isEmpty()
                && grandCamionsLoues.isEmpty() && tresGrandCamionsLoues.isEmpty()) {
            System.out.println("Aucun camion n'a été loués.");
        } else {
            Scanner sc = new Scanner(System.in);
            CamionWroomWroom.afficherCategorie();
            int choix = sc.nextInt();
            while (choix < 1 || choix > 4) {
                System.out.println("Votre choix est invalide \n");
                CamionWroomWroom.afficherCategorie();
                choix = sc.nextInt();
            }
            switch (choix) {
                case 1:
                    petitCamionsDisponibles.add(petitCamionsLoues.get(0));
                    petitCamionsLoues.remove(0);
                    break;
                case 2:
                    moyenCamionsDisponibles.add(moyenCamionsLoues.get(0));
                    moyenCamionsLoues.remove(0);
                    break;
                case 3:
                    grandCamionsDisponibles.add(grandCamionsLoues.get(0));
                    grandCamionsLoues.remove(0);
                    break;
                case 4:
                    tresGrandCamionsDisponibles.add(tresGrandCamionsLoues.get(0));
                    tresGrandCamionsLoues.remove(0);
            }
            System.out.println("\nLe retour du camion a été enregistré\n");
        }
    }

    /**
     * Affiche les catégories
     */
    public static void afficherCategorie() {
        System.out.println("**** Liste des catégories *******");
        System.out.println("1- Petits camions");
        System.out.println("2- Camions moyens");
        System.out.println("3- Grand camions");
        System.out.println("4- Très grands camions");
        System.out.print("Votre choix: ");
    }

    /**
     * Calcule la recette totale
     * @return la recette
     */
    public int calculerRecette(){
        int recette = 0;
        for(Camion c: petitCamionsLoues){
           recette += c.getPrixLocation();
        }
        for(Camion c: moyenCamionsLoues){
           recette += c.getPrixLocation();
        }
        for(Camion c: grandCamionsLoues){
           recette += c.getPrixLocation();
        }
        for(Camion c: tresGrandCamionsLoues){
           recette += c.getPrixLocation();
        }
        recette += totalKilometres * CamionInfo.prixKilometre;
        return recette;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        boolean fin = false;
        CamionWroomWroom camions = new CamionWroomWroom();
        while (!fin) {
            CamionWroomWroom.afficherMenu();
            int choix = sc.nextInt();
            if (choix < 1 || choix > 6) {
                while (choix < 1 || choix > 6) {
                    System.out.println("\nVotre choix est invalide veuillez saisir un numéro entre 1 et 6 inclus\n");
                    CamionWroomWroom.afficherMenu();
                    sc = new Scanner(System.in);
                    choix = sc.nextInt();
                }
            }
            switch (choix) {
                case 1: // afficher les tarifs et capacités
                    CamionWroomWroom.afficherTarifsCapacites();
                    break;
                case 2: // afficher les camions disponibles et loués
                    camions.afficherDisponibilite();
                    break;
                case 3: // évaluer les coûts de location
                    Scanner sc2 = new Scanner(System.in);
                    int poids,
                     volume,
                     kilometres;
                    System.out.println("****** Evaluation des coûts de location *******");
                    //saisie du poids
                    System.out.print("Veuillez saisir le poids désiré: ");
                    poids = sc2.nextInt();
                    while (poids < 0) {
                        System.out.println("Le poids saisi est invalide");
                        System.out.print("Veuillez saisir le poids désiré: ");
                        poids = sc2.nextInt();
                    }
                    //saisie du volume
                    System.out.print("Veuillez saisir le volume désiré: ");
                    volume = sc2.nextInt();
                    while (volume < 0) {
                        System.out.println("Le volume saisi est invalide");
                        System.out.print("Veuillez saisir le volume désiré: ");
                        volume = sc2.nextInt();
                    }
                    //saisie du nombre de kilometres
                    System.out.print("Veuillez saisir le nombre de kilometres désiré: ");
                    kilometres = sc2.nextInt();
                    while (kilometres < 0) {
                        System.out.println("Le nombre de kilometres saisi est invalide");
                        System.out.print("Veuillez saisir le nombre de kilometres désiré: ");
                        kilometres = sc2.nextInt();
                    }
                    try {
                        camions.evaluerCoutLocation(poids, volume, kilometres);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 4:
                    camions.louerCamion();
                    break;
                case 5:
                    camions.retournerCamion();
                    break;
                case 6: // quitter
                    fin = true;
                    System.out.println("~~~~~~~~~ Statistiques ~~~~~~~~~~~~");                    
                    camions.afficherDisponibilite();
                    System.out.println("Recette totale: "+ camions.calculerRecette()+ " Dollars");
                    
                    System.out.println("******* Au revoir! **********");
                    break;

            }
        }
    }
}
